﻿using LightCAD.Runtime;
using OpenTK;
using SkiaSharp;
using SkiaSharp.Views.Desktop;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using static System.Runtime.InteropServices.JavaScript.JSType;

namespace LightCAD.UI
{
    public partial class DrawingEditControl : UserControl, IDrawingEditControl
    {
        internal DocumentRuntime docRt;

        private string activeEditor;

        private ModelSpaceControl modelSpaceControl;
        private ViewportControl activeViewport;

        private PaperSpaceControl paperSpaceControl;
        private Model3DEditControl model3DEditControl;
        private ModelView3DControl modelView3DControl;


        public DrawingEditControl()
        {
            InitializeComponent();
        }
        public DrawingEditControl(DocumentRuntime docRt) : this()
        {
            this.docRt = docRt;
            this.GetEditor(this.editorSelector.EditName);
            this.activeEditor = this.editorSelector.EditName;
            this.Resize += DrawingEditControl_Resize;
        }

        private void DrawingEditControl_Resize(object? sender, EventArgs e)
        {
            if (this.isTwinDisplay)
            {
                editorSelector_TwinDisplay(null, null);
            }
        }

        public IViewportControl[] Viewports => this.modelSpaceControl.Viewports.ToArray();

        public IModel3DEditControl Model3DEditControl => this.model3DEditControl;

        public void SetViewportActive(long vportId)
        {
            foreach (ViewportControl item in Viewports)
            {
                if ((long)item.Tag == vportId)
                {
                    //将文档数据设置为活动
                    docRt.Document.SetActiveViewport(vportId);
                    //将ViewportRuntime设置为活动
                    docRt.DrawingEditRt.ActiveViewportRt = docRt.DrawingEditRt.ViewportRts[vportId];
                    item.Parent.BackColor = Color.Blue;
                    item.IsActive = true;
                }
                else
                {
                    item.Parent.BackColor = Color.White;
                    item.IsActive = false;
                    RefreshViewports(item.ViewportId);//强制刷新不活动的视口，将光标等隐藏
                }
            }

        }

        /// <summary>
        /// 触发刷新视口
        /// </summary>
        /// <param name="vportIds">如果为空，刷新所有视口</param>
        public void RefreshViewports(params long[] vportIds)
        {
            if (vportIds.Length == 0)
            {
                vportIds = this.Viewports.Select((v) => v.ViewportId).ToArray();
            }
            var vports = this.modelSpaceControl.Viewports;
            foreach (var vpctrl in vports)
            {
                var vpId = (long)vpctrl.Tag;
                if (Array.IndexOf(vportIds, vpId) >= 0)
                {
                    vpctrl.ForceRefresh = true;
                    vpctrl.skglControl1.Invalidate();
                }
            }

        }

        internal void InitilizeViewports()
        {
            //由于第一次界面初始化，控件不触发SizeChange事件
            //这里对所有视口强制触发，以完成对视口的初始化
            var vports = this.modelSpaceControl.Viewports;
            foreach (var vpctrl in vports)
            {
                vpctrl.Parent.BackColor = Color.White;
                vpctrl.ViewportControl_SizeChanged(null, null);
            }

            var vport = Viewports[0];
            //将ViewportControl设置为活动
            SetViewportActive(vport.ViewportId);
        }

        private void DrawingControl_Load(object sender, EventArgs e)
        {
        }

        /// <summary>
        /// 跟踪视口点击切换事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Viewport_mouseDown(object? sender, EventArgs e)
        {
            var vpctrl = sender as ViewportControl;
            if (activeViewport == null || vpctrl != activeViewport)
            {
                SetViewportActive((long)vpctrl.Tag);

                activeViewport = vpctrl;
            }
        }

        private void SpaceBar1_SpaceChanged(object? sender, EventArgs e)
        {

        }

        public void AttachSpaceChanged(Action<bool, int> spaceChanged)
        {
        }

        public void DetachSpaceChanged(Action<bool, int> spaceChanged)
        {
        }

        public void SetActive(bool isActive)
        {
            if (isActive)
            {
                this.BringToFront();
                this.Enabled = true;
                SetViewportActive(this.docRt.DrawingEditRt.ActiveViewportRt.Viewport.Id);
                CommandCenter.Instance.BindDocument(this.docRt);
            }
            else
            {
                SetViewportActive(-1);//全部视口不活动
                this.SendToBack();
                this.Enabled = false;
            }
        }

        private void editorSelector_EditChanged(object sender, EventArgs e)
        {
            if (isTwinDisplay)
            {
                for (var i = 0; i < this.pnlEditors.Controls.Count; i++)
                {
                    this.pnlEditors.Controls[i].Visible = false;
                }
                isTwinDisplay = false;
                activeEditor = null;
            }

            var editor = editorSelector.EditName;
            if (activeEditor != null && activeEditor == editor) return;

            if (activeEditor != null)
            {
                GetEditor(activeEditor).SendToBack();
            }
            var control = GetEditor(editor);
            control.Visible = true;
            control.BringToFront();
            control.Dock = DockStyle.Fill;
            RefreshControl(control);
            activeEditor = editor;

        }
        public void RefreshControl(Control control)
        {
            if (control is ModelSpaceControl)
            {

            }
            else if (control is PaperSpaceControl)
            {

            }
            else if (control is Model3DEditControl)
            {
                (control as Model3DEditControl).RefreshControl();
            }
            else if (control is ModelView3DControl)
            {

            }
        }
        private void editorSelector_ContextMenuClick(object sender, EventArgs e)
        {
            var itemName = editorSelector.ContextMenuItemName;
            if (itemName == "mui_NewWindow")
            {
                this.ShowInNewWindow(this.activeEditor);
            }

        }
        private void InitEditor(string editorName)
        {
            if (editorName == "Drawing")
            {
                this.modelSpaceControl.SetLayout(docRt.Document.ActiveLayout);

                var vports = this.modelSpaceControl.Viewports;
                foreach (var vpctrl in vports)
                {
                    vpctrl.mouseDown += Viewport_mouseDown;
                }
            }
            else if (editorName == "Paper")
            {

            }
            else if (editorName == "Model3D")
            {

            }
            else if (editorName == "View3D")
            {

            }
        }

        private Control GetEditor(string editorName)
        {
            for (var i = 0; i < this.pnlEditors.Controls.Count; i++)
            {
                var ctrl = this.pnlEditors.Controls[i];
                if (ctrl.Name == editorName) return ctrl;
            }
            Control editorCtrl = null;
            switch (editorName)
            {
                case "Drawing":
                    this.modelSpaceControl = new ModelSpaceControl();
                    editorCtrl = this.modelSpaceControl;
                    break;
                case "Paper":
                    this.paperSpaceControl = new PaperSpaceControl();
                    editorCtrl = this.paperSpaceControl;
                    break;
                case "Model3D":
                    this.model3DEditControl = new Model3DEditControl();
                    editorCtrl = this.model3DEditControl;
                    this.docRt.DrawingEditRt.InitModel3DEditRuntime();
                    break;
                case "View3D":
                    this.modelView3DControl = new ModelView3DControl();
                    editorCtrl = this.modelView3DControl;
                    break;
            }
            editorCtrl.Dock = DockStyle.Fill;
            editorCtrl.Name = editorName;
            this.pnlEditors.Controls.Add(editorCtrl);
            this.InitEditor(editorName);
            return editorCtrl;
        }
        public void ShowInHost(string editorName)
        {
            editorSelector.SetVisible(editorName, true);
            switch (editorName)
            {
                case "Paper":
                    {

                    }
                    break;
                case "Model3D":
                    {
                        this.model3DEditControl.Dispose();
                        this.model3DEditControl = null;
                        break;
                    }
                case "View3D":
                    {

                        break;
                    }
            }
        }

        private void ShowInNewWindow(string editorName)
        {
            editorSelector.SetVisible(editorName, false);
            editorSelector.btnDrawing.PerformClick();
            switch (editorName)
            {
                case "Paper":
                    {
                        var floatWin = new FloatEditWindow(this.docRt, this, editorName);
                        this.pnlEditors.Controls.Remove(this.paperSpaceControl);
                        this.paperSpaceControl.Dispose();
                        this.paperSpaceControl = floatWin.paperSpaceControl;
                        floatWin.Show(this);
                    }
                    break;
                case "Model3D":
                    {
                        var floatWin = new FloatEditWindow(this.docRt, this, editorName);
                        this.pnlEditors.Controls.Remove(this.model3DEditControl);
                        this.model3DEditControl.Dispose();
                        this.model3DEditControl = floatWin.model3DEditControl;
                        this.docRt.DrawingEditRt.InitModel3DEditRuntime();
                        floatWin.Show(this);
                        break;
                    }
                case "View3D":
                    {
                        var floatWin = new FloatEditWindow(this.docRt, this, editorName);
                        this.pnlEditors.Controls.Remove(this.modelView3DControl);
                        this.modelView3DControl.Dispose();
                        this.modelView3DControl = floatWin.modelView3DControl;
                        floatWin.Show(this);
                        break;
                    }
            }

        }
        private bool isTwinDisplay;
        private void editorSelector_TwinDisplay(object sender, EventArgs e)
        {
            isTwinDisplay = true;
            foreach (Control ctrl in this.pnlEditors.Controls)
                ctrl.Visible = false;

            var editor1 = GetEditor(editorSelector.TwinName1);
            editor1.Visible = true;
            var editor2 = GetEditor(editorSelector.TwinName2);
            editor2.Visible = true;
            editor1.Dock = DockStyle.Left;
            editor1.Width = this.Width / 2 - 1;
            editor2.Dock = DockStyle.Right;
            editor2.Width = this.Width / 2 - 1;
        }
        private void editorSelector_SyncViewportClick(object sender, EventArgs e) 
        {
            this.docRt.DrawingEditRt.Model3DEditRt.SyncViewPort2D(this.docRt.DrawingEditRt.ActiveViewportRt);
        }
    }
}
